﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Web;
using System.Runtime.Serialization;

namespace Share.Models
{
    [DataContract]
    public class Category
    {
        public enum STATUS { Enable, Disable }

        public Category()
        {
            Name = "Untitled category";
            Status = STATUS.Enable;
        }

        [DataMember]
        public int ID { get; set; }

        [Required, MaxLength(50), DataMember]
        public string Name { get; set; }

        [MaxLength(500), DataMember]
        public string Path { get; set; }

        [DataMember]
        public int Level { get; set; }
        
        [MaxLength(200), DataMember]
        public string Description { get; set; }
        
        [MaxLength(200), DataMember]
        public string Photo { get; set; }
        
        [Required, DataMember]
        public STATUS Status { get; set; }

        public virtual Category ParentCategory { get; set; }

        public virtual ICollection<Category> SubCategories { get; set; }

        public virtual ICollection<Item> Items { get; set; }

        public virtual ICollection<Photo> Photos { get; set; }

        public Category FindRootCategory()
        {
            if (this.ParentCategory == null)
                return this;
            else
                return this.ParentCategory.FindRootCategory();
        }
    }

    [DataContract]
    public class Item
    {
        public enum STATUS { Enable, Disable }

        public Item()
        {
        }

        [DataMember]
        public int ID { get; set; }

        [Required]
        [MaxLength(50)]
        [DataMember]
        public string No { get; set; }

        [Required]
        [MaxLength(50)]
        [DataMember]
        public string Name { get; set; }

        [MaxLength(50)]
        [DataMember]
        public string SubName { get; set; }

        [MaxLength(500)]
        [DataMember]
        public string Description { get; set; }

        public string FullDescription { get; set; }
        
        [MaxLength(200)]
        [DataMember]
        public string Photo { get; set; }

        [Required]
        [DefaultValue(false)]
        [DataMember]
        public bool isHot { get; set; }
        [Required]
        [DefaultValue(false)]
        [DataMember]
        public bool isClearance { get; set; }
        [Required]
        [DefaultValue(false)]
        [DataMember]
        public bool isSale { get; set; }
        [Required]
        [DefaultValue(false)]
        [DataMember]
        public bool isNew { get; set; }
        
        [Required]
        [DefaultValue(STATUS.Enable)]
        [DataMember]
        public int Status { get; set; }

        [DataMember]
        public ItemPrice Price { get; set; }

        [DataMember]
        public ItemProperty Metric { get; set; }

        [DataMember]
        public ItemProperty Imperial { get; set; }

        [DataMember]
        public int CaseQty { get; set; }

        [DataMember]
        public ItemProperty CaseMetric { get; set; }

        [DataMember]
        public ItemProperty CaseImperial { get; set; }

        public virtual ICollection<Category> Catrgories { get; set; }

        public virtual ICollection<Photo> Photos { get; set; }

        public virtual ICollection<Item> AlsoLikes { get; set; }

        public virtual ICollection<Comment> Comments { get; set; }
    }

    public class ItemPrice
    {
        public decimal List { get; set; }
        public decimal Basic { get; set; }
        public decimal Silver { get; set; }
        public decimal Gold { get; set; }
        public decimal Platium { get; set; }
        public decimal WholeSale { get; set; }
    }

    public class ItemProperty
    {
        public decimal NetWeight { get; set; }
        public decimal NetCount { get; set; }
        public decimal GrossWeight { get; set; }
        public decimal GrossCount { get; set; }
        public decimal DimensionL { get; set; }
        public decimal DimensionW { get; set; }
        public decimal DimensionH { get; set; }
    }
    
    public class Photo
    {
        public int ID { get; set; }

        [Required]
        public string URL { get; set; }
    }

    public class ShoppingCart
    {
        public int ID { get; set; }

        [Required]
        public int Qty { get; set; }

        [Required]
        public DateTime AddAt { get; set; }

        [Required]
        public virtual Item Item { get; set; }

        [Required]
        public virtual Customer Customer { get; set; }
    }

    public class Customer
    {
        public enum STATUS { Enable, Disable }
        
        public enum LEVEL { Basic, Silver, Glod, Platium }

        public int ID { get; set; }

        [Required]
        public string Email { get; set; }
        
        [Required]
        public string Password { get; set; }
        
        [Required]
        public string FirstName { get; set; }
        
        [Required]
        public string LastName { get; set; }
        
        [Required]
        public string Mobile { get; set; }
        
        [Required]
        public string Phone { get; set; }
        
        [Required]
        [DefaultValue(LEVEL.Basic)]
        public int Level { get; set; }
        
        [Required]
        [DefaultValue(STATUS.Enable)]
        public int Status { get; set; }
        
        [Required]
        public virtual Country Country { get; set; }
        
        [Required]
        public virtual State State { get; set; }
        
        [Required]
        public DateTime RegisterAt { get; set; }

        public virtual BillingAddress BillingAddress { get; set; }
        
        public virtual ICollection<ShippingAddress> ShippingAddresses { get; set; }
    }

    [Table("ShippingAddress")]
    public class ShippingAddress : Address
    {
    }

    [Table("BillingAddress")]
    public class BillingAddress : Address
    {
    }

    public class Country
    {
        public int ID { get; set; }

        [Required]
        public string Code { get; set; }

        [Required]
        public string Name { get; set; }
        
        public ICollection<State> States { get; set; }
    }

    public class State
    {
        public int ID { get; set; }
        
        [Required]
        public string Code { get; set; }
        
        [Required]
        public string Name { get; set; }
    }

    public class Address
    {
        public int ID { get; set; }
        
        [Required]
        public virtual Country Country { get; set; }
        
        [Required]
        public virtual State State { get; set; }
        
        [Required]
        public string Address1 { get; set; }
        public string Address2 { get; set; }
        public string Address3 { get; set; }
        
        [Required]
        public string PostalCode { get; set; }
    }

    public class Order
    {
        public enum STATUS { Pending, Paid, Shipped, Confirmed }

        public int ID { get; set; }

        [Required]
        public string Num { get; set; }

        [Required]
        public DateTime CreateAt { get; set; }
        
        [Required]
        [DefaultValue(0)]
        public decimal Tax { get; set; }
        
        [Required]
        [DefaultValue(0)]
        public decimal ShippingRate { get; set; }

        public virtual GiftCard GiftCard { get; set; }
        
        [Required]
        [DefaultValue(0)]
        public decimal GCValue { get; set; }

        public virtual StoreCredit StoreCredit { get; set; }
        
        [Required]
        [DefaultValue(0)]
        public decimal SCValue { get; set; }

        [Required]
        [DefaultValue(STATUS.Pending)]
        public int Status { get; set; }

        [Required]
        public virtual Customer Customer { get; set; }
        
        [Required]
        public virtual ShippingMethod ShippingMethod { get; set; }
        
        [Required]
        public virtual PaymentMethod PaymentMethod { get; set; }

        public virtual ICollection<OrderDetail> OrderDetails { get; set; }
    }

    public class OrderDetail
    {
        public int ID { get; set; }

        [Required]
        public int Qty { get; set; }
        
        [Required]
        public decimal DealPrice;

        [Required]
        public virtual Item Item { get; set; }
    }

    public class ShippingMethod
    {
        public int ID { get; set; }
        public string Provider { get; set; }
        public string Method { get; set; }
        
        [Required]
        [DefaultValue(0)]
        public decimal Rate { get; set; }
    }

    public class PaymentMethod
    {
        private enum METHOD { PayPal, CreditCard }
        private enum CCTYPE { Visa, Master }

        public int ID { get; set; }
        
        [Required]
        [DefaultValue(METHOD.PayPal)]
        public int Type { get; set; }
        
        public string PayPalAccount { get; set; }
        
        public string CCType { get; set; }
        
        public string CCNum { get; set; }
        
        public string CCOwner { get; set; }
    }

    public class GiftCard
    {
        public int ID { get; set; }

        [Required]
        public string Num { get; set; }
        
        [Required]
        public decimal InitValue { get; set; }
        
        [Required]
        public decimal Balance { get; set; }
        
        [Required]
        public virtual Customer Buyer { get; set; }
    }

    public class StoreCredit
    {
        public int ID { get; set; }

        [Required]
        public decimal Balance { get; set; }
        
        [Required]
        public virtual Customer Customer { get; set; }
    }

    public class Adv
    {
        public enum POSITION { HomeBanner, HomePromotion }
        public enum METHOD { Current, Blank }

        public int ID { get; set; }

        [Required]
        public string Photo { get; set; }

        [Required]
        public int Position { get; set; }
        
        [Required]
        [DefaultValue(METHOD.Current)]
        public int Method { get; set; }

        public string Url { get; set; }
    }

    public class Comment
    {
        public enum STATUS { Show, Hide }

        public int ID { get; set; }

        [Required]
        public string Title { get; set; }

        [Required]
        public string Content { get; set; }

        [Required]
        [DefaultValue(5)]
        public int Rate { get; set; }

        [Required]
        public DateTime CreateAt { get; set; }

        [Required]
        [DefaultValue(STATUS.Show)]
        public int Status { get; set; }

        public virtual Item Item { get; set; }

        public virtual Customer Customer { get; set; }
    }

    public class Directory
    {
        public int ID { get; set; }

        [Required]
        public string Name { get; set; }
        
        [Required]
        public string Path { get; set; }
        
        [Required]
        public int Level { get; set; }

        public virtual Directory Parent { get; set; }

        public virtual ICollection<Directory> Subs { get; set; }

        public Directory()
        {
            Name = "Untitled";
            Path = "/";
            Level = 0;
        }
    }

    public class DB : DbContext
    {
        public DbSet<Category> Categories { get; set; }
        public DbSet<Item> Items { get; set; }
        public DbSet<Photo> Photos { get; set; }
        public DbSet<Country> Countries { get; set; }
        public DbSet<State> States { get; set; }
        public DbSet<Customer> Customers { get; set; }
        public DbSet<ShippingAddress> ShippingAddresses { get; set; }
        public DbSet<BillingAddress> BillingAddresses { get; set; }
        public DbSet<ShoppingCart> ShoppingCarts { get; set; }
        public DbSet<Order> Orders { get; set; }
        public DbSet<OrderDetail> OrderDetails { get; set; }
        public DbSet<ShippingMethod> ShippingMethods { get; set; }
        public DbSet<PaymentMethod> PaymentMethods { get; set; }
        public DbSet<GiftCard> GiftCards { get; set; }
        public DbSet<StoreCredit> StoreCredits { get; set; }
        public DbSet<Adv> Advs { get; set; }
        public DbSet<Comment> Comments { get; set; }
        public DbSet<Directory> Directories { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Item>().HasMany(m => m.AlsoLikes).WithMany();
        }

        public static DB Current
        {
            get
            {
                string ocKey = "ocm_" + HttpContext.Current.GetHashCode().ToString("x");
                if (!HttpContext.Current.Items.Contains(ocKey))
                    HttpContext.Current.Items.Add(ocKey, new DB());
                return HttpContext.Current.Items[ocKey] as DB;
            }
        }    
    }
}